/*
    $Header: /Windows/Shell/ShellExt.root/ShellExt/src/CIShellExtImp.cpp 1     08-01-05 0:08 Ken $
    $Log: /Windows/Shell/ShellExt.root/ShellExt/src/CIShellExtImp.cpp $
 * 
 * 1     08-01-05 0:08 Ken
*/


#include "StdAfx.h"
#include ".\cishellextimp.h"


/////////////////////////////////////////////////////////////////////////////
// IShellExtInit interface
HRESULT CIShellExtInitImp::Initialize ( LPCITEMIDLIST pidlFolder, LPDATAOBJECT  pDataObj, HKEY hProgID)
{
    //
    // get the target objects first
    //
    TCHAR szTgt[MAX_PATH];
    TCHAR* pszTgt;

    if ( FALSE!=SHGetPathFromIDList (pidlFolder, szTgt))
    {
        pszTgt=szTgt;
    }
    else
    {
        pszTgt=NULL;
    }

    if(FALSE==VTgtInit(pszTgt))
    {
        return E_FAIL;
    }


    //
    // get the source objects
    //
    FORMATETC fmt = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
    STGMEDIUM stg = { TYMED_HGLOBAL };
    // Look for CF_HDROP data in the data object.
    if ( FAILED( pDataObj->GetData ( &fmt, &stg )))
    {
        // Nope! Return an "invalid argument" error back to Explorer.
        return E_INVALIDARG;
    }

    // Get a pointer to the actual data.
    HDROP    hDrop = (HDROP) GlobalLock ( stg.hGlobal );
    if ( NULL == hDrop )
        return E_INVALIDARG;


    HRESULT hr=S_OK;
    // Determine how many files were dropped.
    UINT    uNumFiles = DragQueryFile ( hDrop, 0xFFFFFFFF, NULL, 0 );
    int iValidSrc=0;
    if(FALSE==VPreSrcInit(uNumFiles))
    {
        hr=E_FAIL;
    }
   else
   {
        TCHAR    szFile [MAX_PATH];
        // Check each item.
        for (UINT uFile = 0; uFile < uNumFiles; uFile++ )
        {
            if ( DragQueryFile ( hDrop, uFile, szFile, MAX_PATH ))
            {
                BOOL fRet=VSrcInit(uFile, szFile);
                if (FALSE==fRet)
                {
                    hr=E_FAIL;
                    break;
                }
            }
        }
   }

    GlobalUnlock ( stg.hGlobal );
    ReleaseStgMedium ( &stg );

    return hr;
}

/////////////////////////////////////////////////////////////////////////////
// IPersistFile interface
HRESULT CIShellExtInitImp::Load ( LPCOLESTR wszFilename, DWORD dwMode )
{
    USES_CONVERSION;     //some convert var defines
    COLE2CT pszFileName(wszFilename);
    return (FALSE==VSrcInit(0, pszFileName, TRUE)) ? E_FAIL :S_OK;
}

/////////////////////////////////////////////////////////////////////////////
// IContextMenu interface
HRESULT CIShlCntxMenuImp::QueryContextMenu ( HMENU hmenu, UINT uMenuIndex
                                            , UINT  uidFirstCmd, UINT uidLastCmd, UINT  uFlags )
{
    // If the flags include CMF_DEFAULTONLY then we shouldn't do anything.
    if ( uFlags & CMF_DEFAULTONLY )
    {
        return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, 0 );
    }

    HMENU hmenuTop = CreatePopupMenu();

    DWORD dwCmdNumb=VGetCmdNumb();
    // Add the menu item.
    for( DWORD i=0, uMenuId=0; i < dwCmdNumb; i++, uidFirstCmd++ )
    {
        if( VIsCmdValid( i ) )
        {
            InsertMenu( hmenuTop, uMenuId, MF_STRING | MF_BYPOSITION, uidFirstCmd, VGetMenuString(i));
            if ( NULL != VGetMenuBmp(i) )
            {
                SetMenuItemBitmaps ( hmenu, uMenuId, MF_POPUP | MF_BYPOSITION, VGetMenuBmp(i), NULL );
            }
            uMenuId++;
        }
    }
    InsertMenu ( hmenu, uMenuIndex, MF_POPUP | MF_BYPOSITION, (UINT)hmenuTop, _T("ShellExt"));

    // Return 1 to tell the shell that we added 1 top-level menu item.
    return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, dwCmdNumb);
}

/////////////////////////////////////////////////////////////////////////////
// IContextMenu interface
HRESULT CIShlCntxMenuImp::GetCommandString( UINT idCmd, UINT uFlags,
    UINT* pwReserved, LPSTR pszName, UINT cchMax )
{
    const TCHAR* szCmdStr=VGetCmdHit(idCmd);
    if(NULL==szCmdStr)
        return E_FAIL;
    USES_CONVERSION;     //some convert var defines

    if ( VGetCmdNumb() <= idCmd )
        return E_INVALIDARG;

    //we only support help string now
    if ( uFlags & GCS_HELPTEXT )
    {
        if ( uFlags & GCS_UNICODE )
        {
            // convert pszName to Unicode
            wcsncpy ( (LPWSTR) pszName, T2CW(szCmdStr), cchMax );
        }
        else
        {
            // use ascii version
            strncpy ( pszName, T2CA(szCmdStr), cchMax );
        }
        return S_OK;
    }
    return E_INVALIDARG;
}

/////////////////////////////////////////////////////////////////////////////
// IContextMenu interface
HRESULT CIShlCntxMenuImp::InvokeCommand ( LPCMINVOKECOMMANDINFO pInfo )
{
    // we not support verb call
    if ( 0 != HIWORD(pInfo->lpVerb) )
    {
        return E_INVALIDARG;
    }

    // we have only one menu item
    WORD wCmdId=LOWORD(pInfo->lpVerb);
    if ( VGetCmdNumb() <= wCmdId )
    {
        return E_INVALIDARG;
    }

    // Invoke Command
    VInvokeCommand(pInfo, wCmdId);
    return S_OK;
}

HRESULT CIShlIconImp::GetOverlayInfo( LPWSTR pwszIconFile, int cchMax, int *pIndex, DWORD *pdwFlags)
{
    if(cchMax <= m_dwNameLen )
    {
        return E_FAIL;
    }

    wcsncpy( pwszIconFile,m_wszIconFileName, cchMax );
    *pdwFlags=ISIOI_ICONFILE|ISIOI_ICONINDEX;
    *pIndex=m_iIndex;

    return S_OK;
}
